package com.example.smart.controller;

import cn.hutool.crypto.SecureUtil;
import com.example.common.config.JwtHelper;
import com.example.smart.enums.AdminReview;
import com.example.smart.pojo.Admin;
import com.example.smart.security.AccountAdmin;
import com.example.smart.service.AdminService;
import com.example.common.enums.BusinessType;
import com.example.common.util.R;
import com.example.common.util.Utils;
import com.example.smart.annotation.Log;
import com.example.smart.util.RedisCache;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping(value = "/admin/")
@Tag(name = "显示管理员数据")
public class AdminController {
    @Autowired
    private AdminService adminService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private RedisCache redisCache;

    @PreAuthorize("hasAuthority('admin:list')")
    @Operation(summary = "获得所有的管理员")
    @Log(title = "管理员管理", businessType = BusinessType.SELECT)
    @GetMapping(value = "/getAllAdmin")
    public R getAllAdmin() {
        List<Admin> admins = adminService.list();
        return R.ok("查询所有管理员成功").data("admins", admins);
    }

    @Operation(summary = "登录管理员")
    @Log(title = "管理员管理", businessType = BusinessType.LOGIN)
    @PostMapping(value = "/login")
    public R login(@RequestBody Admin admin, HttpSession session) {
        Map<String, Object> map = adminService.login(admin);
        if (map.get("state").equals("success")) {
            Map<String, Object> maps = new HashMap<>();
            session.setAttribute("admin", admin);
            maps.put("admin", admin);
            maps.put("token", map.get("token"));

            return R.ok("管理员登录成功").data(maps);
            /*if (admin.getAdminId() != null && admin.getAdminId() == 1) {
                Map<String, Object> maps = new HashMap<>();
                maps.put("admin", admin);
                maps.put("token", map.get("token"));
                return R.ok("超级管理员登录成功").data(maps);
            } else {
                Map<String, String> statusMap = new HashMap<>();
                statusMap.put("APPROVED", "管理员登录成功");
                statusMap.put("FAILED", "管理员登录失败，请你联系超级管理员");
                statusMap.put("CANCELED", "管理员登录失败，你的账号未注册");
                statusMap.put("FROZEN", "你的账号已被永久冻结，请你联系超级管理员");

                String statusMessage = statusMap.get(admin.getAdminReview().name());
                if (admin.getAdminReview() == AdminReview.APPROVED) {
                    String adminName = admin.getAdminName();
                    String adminEmail = admin.getAdminEmail();
                    String adminPhone = admin.getAdminPhone();
                    String jwtToken;
                    if (adminName != null) {
                        jwtToken = jwtHelper.getToken(adminName, "admin");
                    } else if (adminEmail != null){
                        jwtToken = jwtHelper.getToken(adminEmail, "admin");
                    } else if (adminPhone != null) {
                        jwtToken = jwtHelper.getToken(adminPhone, "admin");
                    } else {
                        return R.ok("管理员登录失败").data(map);
                    }
                    return R.ok(statusMessage).data("admin", admin).data("token", jwtToken);
                } else if (admin.getAdminReview() == AdminReview.FAILED || admin.getAdminReview() == AdminReview.CANCELED) {
                    return R.ok(statusMessage).data("admin", admin);
                } else if (admin.getAdminStatus() == AccountStatus.FROZEN) {
                    if (admin.getAdminStatus() == AccountStatus.FROZEN) {
                        return R.ok(statusMessage).data("admin", admin);
                    } else {
                        // 自动解冻别忘记修改功能或者是登录功能那个东西才能实现方法
                        Duration duration = Duration.between(admin.getStarStatusTime().toInstant(), admin.getEndStatusTime().toInstant());
                        long days = duration.toDays();
                        long hours = duration.toHours() % 24;
                        long minutes = duration.toMinutes() % 60;
                        long seconds = duration.getSeconds() % 60;
                        return R.ok("你的账号已被临时冻结，剩余时间" + days + "天" + hours + "小时" + minutes + "分钟" + seconds + "秒，会自动解冻").data("admin", admin);
                    }
                }
            }*/
        } else {
            return R.ok("管理员登录失败").data(map);
        }
        //return R.ok("管理员登录失败").data(map);
    }

    @PreAuthorize("hasAuthority('admin:logout')")
    @Operation(summary = "管理员退出登录")
    @Log(title = "管理员管理", businessType = BusinessType.LOGOUT)
    @PostMapping(value = "/logout")
    public R logout() {
        UsernamePasswordAuthenticationToken authenticationToken = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        AccountAdmin accountAdmin = (AccountAdmin) authenticationToken.getPrincipal();
        redisCache.deleteObject("admin_token:" + accountAdmin.getAdmin().getAdminId());
        return R.ok("管理员退出登录成功");
    }
    //登录和退出登录日志记录


    @Operation(summary = "注册管理员")
    @Log(title = "管理员管理", businessType = BusinessType.INSERT)
    @PostMapping(value = "/register")
    public R addAdmin(@RequestBody Admin admin) {
        String password = passwordEncoder.encode(admin.getPassword());
        String salt = Utils.salt();
        admin.setPassword(SecureUtil.md5(password + salt));
        admin.setAdminSalt(salt);
        boolean flag = adminService.save(admin);
        if (flag) {
            if (admin.getAdminId() == 1) {
                String jwtToken = JwtHelper.getToken(admin.getAdminId(), admin.getAdminName(), "admin");
                return R.ok("超级管理员注册成功").data("token", jwtToken);
            }/* else {
                admin.setAdminReview(AdminReview.PENDING_AUDIT);
               if (admin.getAdminReview() == AdminReview.PENDING_AUDIT) {
                    return R.ok("管理员注册成功，等待审核账号");
               }
            }*/
        }
        return R.error("管理员注册失败");
        //注册功能需要做审核的，如果超级管理员审核通过后才能管理员注册成功
    }

    @PreAuthorize("hasAuthority('admin:delete')")
    @Operation(summary = "注销管理员数据")
    @Log(title = "管理员管理", businessType = BusinessType.DELETE)
    @DeleteMapping(value = "/deleteAdmin/{adminId}")
    public R deleteAdmin(@PathVariable("adminId") Integer adminId) {
        boolean flag = adminService.removeById(adminId);
        if (flag) {
            return R.ok("管理员注销成功");
        } else {
            return R.error("管理员注销失败");
        }
    }

    @PreAuthorize("hasAuthority('admin:getById')")
    @Operation(summary = "按照管理员编号查询数据")
    @Log(title = "管理员管理", businessType = BusinessType.SELECT)
    @GetMapping(value = "/getAdminById/{adminId}")
    public R getByIdAdmin(@PathVariable("adminId") Integer adminId) {
        Admin admin = adminService.getById(adminId);
        return R.ok("按照管理员编号查询数据成功").data("admin", admin);
    }

    @PreAuthorize("hasAuthority('admin:update')")
    @Operation(summary = "修改管理员数据")
    @Log(title = "管理员管理", businessType = BusinessType.UPDATE)
    @PutMapping(value = "/updateAdmin")
    public R updateAdmin(@RequestBody Admin admin) {
        String salt = Utils.salt();
        admin.setPassword(SecureUtil.md5(admin.getPassword() + salt));
        admin.setAdminSalt(salt);
        boolean flag = adminService.updateById(admin);
        if (flag) {
            return R.ok("管理员修改成功");
        } else {
            return R.error("管理员修改失败");
        }
    }
}
